# storage/page.py

"""
定义了数据库页面的内存表示。
一个页面是存储系统的最小数据单元。
"""

import threading

PAGE_SIZE = 4096  # 4KB，假设每页大小固定


class Page:
    """
    表示内存中的一个数据页面。

    属性:
        page_id (int): 页面在文件中的唯一标识符。
        data (bytearray): 存储页面数据的字节数组。
        is_dirty (bool): 标记页面是否被修改过。如果为True，
                         在被淘汰前必须写回磁盘。
        pin_count (int): 引用计数，表示当前有多少个事务正在使用该页面。
                         pin_count > 0 的页面不能被淘汰。
        lock (threading.Lock): 
            为每个页面添加一个独立的锁，用于保护该页面的pin_count和is_dirty状态，
            实现细粒度并发控制。
    """

    def __init__(self, page_id: int, data: bytes = None):
        self.page_id = page_id
        self.data = bytearray(data) if data else bytearray(PAGE_SIZE)
        self.is_dirty = False
        self.pin_count = 0
        self.lock = threading.Lock() # <-- 新增：页面自己的锁

    def __repr__(self):
        # 增加repr方法，方便调试时查看页面状态
        return f"Page(id={self.page_id}, dirty={self.is_dirty}, pin_count={self.pin_count})"

    def get_data(self) -> bytearray:
        """获取页面数据。"""
        return self.data

    def set_data(self, data: bytes):
        """
        设置页面数据并标记为脏页。
        这模拟了数据库引擎对页面内容的修改操作。
        """
        if len(data) > PAGE_SIZE:
            raise ValueError("Data exceeds page size.")

        # --- 核心修正 ---
        # 1. 先用空字节将整个页面清空，确保旧数据被彻底擦除
        self.data = bytearray(PAGE_SIZE)
        # 2. 然后再写入新的数据
        self.data[:len(data)] = data
        # --- 修正结束 ---

        self.is_dirty = True